package org.zpmis.api.business;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
import org.zpmis.common.base.AdminLoginUser;
import org.zpmis.common.base.AppletsLoginUser;
import org.zpmis.common.base.BaseWebService;
import org.zpmis.common.enums.SequenceEnum;
import org.zpmis.common.exception.BusinessException;
import org.zpmis.common.result.ResultCode;
import org.zpmis.common.utils.StringUtil;
import org.zpmis.domain.contract.enums.ContractBillEnum;
import org.zpmis.domain.contract.enums.ContractEnum;
import org.zpmis.domain.contract.model.Contract;
import org.zpmis.domain.contract.model.ContractBill;
import org.zpmis.domain.contract.qo.AddContractQo;
import org.zpmis.domain.contract.qo.ContractDetailQo;
import org.zpmis.domain.contract.qo.ContractListQo;
import org.zpmis.domain.contract.service.ContractBillService;
import org.zpmis.domain.contract.service.ContractService;
import org.zpmis.domain.contract.vo.ContractBillListVo;
import org.zpmis.domain.contract.vo.ContractVo;
import org.zpmis.domain.sequence.service.SequenceService;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created with CodeGenerator
 * Description:
 * @author  Yang
 * Date: 2021-6-2
 * Time: 14:52:19
 */
@Service
@Slf4j
public class ContractWebService extends BaseWebService {
    @Reference
    private ContractService contractService;

    @Reference
    private SequenceService sequenceService;

    @Reference
    private ContractBillService contractBillService;


    /**
     * 新增合同
     * @param addContractQo
     */
    public void addContract(AddContractQo addContractQo) throws BusinessException,Exception{
        //获取当前登录用户
        AdminLoginUser adminLoginUser = super.getAdminLoginUser();
        if(adminLoginUser == null){
            throw new BusinessException(ResultCode.USER_NOT_LOGIN);
        }
        contractService.save(
            Contract.builder()
                    .companyId(addContractQo.getCompanyId())
                    .code(sequenceService.getSequenceNum(SequenceEnum.CONTRACT))
                    .name(addContractQo.getName())
                    .contractTime(addContractQo.getContractTime())
                    .contractDesc(addContractQo.getContractDesc())
                    .aCompanyName(addContractQo.getACompanyName())
                    .aCharge(addContractQo.getACharge())
                    .aTalkPerson(addContractQo.getATalkPerson())
                    .aTalkMobile(addContractQo.getATalkMobile())
                    .bCompanyName(addContractQo.getBCompanyName())
                    .bCharge(addContractQo.getBCharge())
                    .bTalkPerson(addContractQo.getBTalkPerson())
                    .bTalkMobile(addContractQo.getBTalkMobile())
                    .cCompanyName(addContractQo.getCCompanyName())
                    .cCharge(addContractQo.getCCharge())
                    .cTalkPerson(addContractQo.getCTalkPerson())
                    .cTalkMobile(addContractQo.getCTalkMobile())
                    .signMode(addContractQo.getSignMode())
                    .content(addContractQo.getContent())
                    .licenseAttachment(addContractQo.getLicenseAttachment())
                    .totalAmount(StringUtil.isEmpty(addContractQo.getTotalAmount()) ? BigDecimal.ZERO : new BigDecimal(addContractQo.getTotalAmount()).setScale(4))
                    .contractAttachment(addContractQo.getContractAttachment())
                    .remark(addContractQo.getRemark())
                    .effectiveTime(addContractQo.getEffectiveTime())
                    .endTime(addContractQo.getEndTime())
                    .type(addContractQo.getType())
                    .createId(adminLoginUser.getId())
                    .createPerson(adminLoginUser.getUserName())
                    .createTime(Instant.now().toEpochMilli())
                    .isDeleted(ContractEnum.NOT_DELETE.code())
                    .status(ContractEnum.PROCESS_STATUS.code())
                    .build()
        );
    }

    /**
     * 合同列表查询
     * @param contractListQo
     * @return
     */
    public PageInfo contractList(ContractListQo contractListQo) {
        Long companyId = contractListQo.getCompanyId();
        String code = contractListQo.getCode();
        Integer status = contractListQo.getStatus();
        String name = contractListQo.getName();
        Integer type = contractListQo.getType();
        Long startTime = contractListQo.getStartTime();
        Long endTime = contractListQo.getEndTime();
        Condition condition = new Condition(Contract.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("isDeleted",ContractEnum.NOT_DELETE.code());
        if(companyId != null){
            criteria.andEqualTo("companyId",companyId);
        }
        if(status != null){
            criteria.andEqualTo("status",status);
        }
        if(type != null){
            criteria.andEqualTo("type",type);
        }
        if(StringUtil.isNotEmpty(code)){
            criteria.andLike("code","%"+code+"%");
        }
        if(StringUtil.isNotEmpty(name)){
            criteria.andLike("name","%"+name+"%");
        }
        if(startTime != null && endTime != null){
            criteria.andGreaterThanOrEqualTo("createTime",startTime);
            criteria.andLessThanOrEqualTo("createTime",endTime);
        }
        if(startTime != null && endTime == null){
            criteria.andGreaterThanOrEqualTo("createTime",startTime);
            criteria.andLessThanOrEqualTo("createTime",Instant.now().toEpochMilli());
        }
        if(startTime == null && endTime != null){
            criteria.andLessThanOrEqualTo("createTime",endTime);
        }
        condition.orderBy("createTime").desc();
        PageHelper.startPage(contractListQo.getPageNum(),contractListQo.getPageSize());
        List<Contract> contractList = contractService.findByCondition(condition);
        PageInfo pageInfo = new PageInfo<>(contractList);
        //自定义返回结果
        List<ContractVo> resultList = contractList.stream().map(ContractVo::new).collect(Collectors.toList());
        pageInfo.setList(resultList);
        return pageInfo;
    }

    /**
     * 查询合同详情
     * @param contractDetailQo
     * @return
     */
    public ContractVo contractDetail(ContractDetailQo contractDetailQo) throws BusinessException,Exception{
        Contract contract = contractService.findById(contractDetailQo.getId());
        if(contract == null){
            throw new BusinessException(ResultCode.DATA_NOT_FOUND);
        }
        ContractVo resultVo = new ContractVo(contract);
        //根据合同查询账单
        Condition condition = new Condition(ContractBill.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("isDeleted", ContractBillEnum.NOT_DELETE.code());
        criteria.andEqualTo("contractId",contract.getId());
        condition.orderBy("actualTime").asc();
        List<ContractBill> contractBillList = contractBillService.findByCondition(condition);
        if(contractBillList != null && !contractBillList.isEmpty()){
            List<ContractBillListVo> contractBillListVoList = contractBillList.stream().map(ContractBillListVo::new).collect(Collectors.toList());
            resultVo.setContractBillListVoList(contractBillListVoList);
        }
        return resultVo;
    }


    /**
     * 判断当前小程序登录用户是否签订入网合同
     * @return
     */
    public ResultCode checkOrderContract() throws BusinessException,Exception{
        //获取当前登录用户
        AppletsLoginUser appletsLoginUser = super.getAppletsLoginUser();
        if(appletsLoginUser == null){
            throw new BusinessException(ResultCode.USER_NOT_LOGIN);
        }
        Long companyId = appletsLoginUser.getCompanyId();
        //根据用户企业id 查询是否存在有效期内的入网合同
        //TODO 目前没有审核功能 后期加入审核功能是 此处需要判断审核状态是否是已签订
        Condition condition = new Condition(Contract.class);
        condition.createCriteria()
                .andEqualTo("companyId",companyId)
                .andEqualTo("isDeleted", ContractEnum.NOT_DELETE.code())
                //.andEqualTo("status", ContractEnum.COMPLETE_STATUS.code())
                .andEqualTo("type", ContractEnum.NET_IN_TYPE.code())
                .andGreaterThanOrEqualTo("endTime",Instant.now().toEpochMilli())
                .andLessThanOrEqualTo("effectiveTime",Instant.now().toEpochMilli());
        List<Contract> contractList = contractService.findByCondition(condition);
        if(contractList == null || contractList.isEmpty()){
            return ResultCode.ORDER_APPLY_CHECK_ERROR;
        }
        return ResultCode.SUCCESS;
    }

    /**
     * 删除合同
     * @param contractDetailQo
     * @throws BusinessException
     * @throws Exception
     */
    public void deleteContract(ContractDetailQo contractDetailQo) throws BusinessException,Exception{
        Contract contract = contractService.findById(contractDetailQo.getId());
        if(contract == null){
            throw new BusinessException(ResultCode.DATA_NOT_FOUND);
        }
        //根据合同查询账单
        Condition condition = new Condition(ContractBill.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("isDeleted", ContractBillEnum.NOT_DELETE.code());
        criteria.andEqualTo("contractId",contract.getId());
        List<ContractBill> contractBillList = contractBillService.findByCondition(condition);
        //合同有账单信息,不允许删除
        if(!contractBillList.isEmpty()){
            throw new BusinessException(ResultCode.DATA_ALREADY_RELATION_EXISTS);
        }
        //执行删除
        contractService.update(Contract.builder().id(contract.getId()).isDeleted(ContractEnum.DELETED.code()).build());
    }
}
